{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "scikit-learn库，实现了一系列数据挖掘算法，提供通用编程接口、标准化的测试和调参工具，便于用户尝试不同算法对其进行充分测试和查找最优参数值。\n",
    "估计器（Estimator）：用于分类、聚类和回归分析。\n",
    "转换器（Transformer）：用于数据预处理和数据转换。\n",
    "流水线（Pipeline）：组合数据挖掘流程，便于再次使用。\n",
    "为帮助用户实现大量分类算法，scikit-learn把相关功能封装成所谓的估计器。估计器用于分类任务，它主要包括以下两个函数。\n",
    "fit()：训练算法，设置内部参数。该函数接收训练集及其类别两个参数。\n",
    "predict()：参数为测试集。预测测试集类别，并返回一个包含测试集各条数据类别的数组。\n",
    "大多数scikit-learn估计器接收和输出的数据格式均为numpy数组或类似格式。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import csv\n",
    "import os\n",
    "# 加载数据\n",
    "data_filename = os.path.join(\"E:/pythonTest/Chapter 2\",\"ionosphere.data\")\n",
    "x = np.zeros((351,34),dtype=\"float\")\n",
    "y = np.zeros((351,),dtype=\"bool\")\n",
    "with open(data_filename,\"r\") as input_file:\n",
    "    reader = csv.reader(input_file)\n",
    "    for i,row in enumerate(reader):\n",
    "        data = [float(datum) for datum in row[:-1]]\n",
    "        x[i] = data\n",
    "        y[i] = row[-1] ==\"g\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from sklearn.cross_validation import train_test_split\n",
    "x_train,x_test,y_train,y_test = train_test_split(x,y) # 创建训练集和测试集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The accuracy is 83.0%\n"
     ]
    }
   ],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier #导入K近邻分类器这个类\n",
    "estimator = KNeighborsClassifier()#初始化一个实例 默认选择5个近邻作为分类依据\n",
    "estimator.fit(x_train,y_train) #K近邻估计器分析训练集中的数据，比较待分类的新数据点和训练集中的数据，找到新数据点的近邻。\n",
    "y_predicted = estimator.predict(x_test) #测试集测试算法\n",
    "accuracy = np.mean(y_test == y_predicted) * 100 #评估它在测试集上的表现\n",
    "print(\"The accuracy is {0:.1f}%\".format(accuracy))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The average accuracy is 82.3%\n"
     ]
    }
   ],
   "source": [
    "#交叉检验\n",
    "from sklearn.cross_validation import cross_val_score\n",
    "scores = cross_val_score(estimator,x,y,scoring=\"accuracy\")\n",
    "average_accuracy = np.mean(scores)*100\n",
    "print(\"The average accuracy is {0:.1f}%\".format(average_accuracy))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 测试一系列n_neighbors的值，比如从1到20，可以重复进行多次实验，观察不同的参数值所带来的结果之间的差异。\n",
    "avg_scores = []\n",
    "all_scores = []\n",
    "parameter_values = list(range(1,21))\n",
    "for n_neighbors in parameter_values:\n",
    "    estimator = KNeighborsClassifier(n_neighbors=n_neighbors) #参数 n_neighbors过小时，分类结果容易受干扰，随机性很强。相反，如果n_neighbors过大，实际近邻的影响将削弱。\n",
    "    scores = cross_val_score(estimator,x,y,scoring=\"accuracy\")\n",
    "    #不同n_neighbors值的得分和平均分保存起来，留作分析用\n",
    "    avg_scores.append(np.mean(scores))\n",
    "    all_scores.append(scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x20f49fdf8d0>]"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x20f49b9e8d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline #需要告诉IPython Notebook，我们要在笔记本中作图\n",
    "from matplotlib import pyplot as plt #从matplotlib库导入pyplot\n",
    "plt.plot(parameter_values,avg_scores,\"-o\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The original average accuracy for is82.3%\n",
      "The 'broken' average accuracy for is71.5%\n"
     ]
    }
   ],
   "source": [
    "x_broken = np.array(x)\n",
    "x_broken[:,::2] /= 10\n",
    "estimator = KNeighborsClassifier()\n",
    "original_scores = cross_val_score(estimator, x, y,scoring='accuracy')\n",
    "print(\"The original average accuracy for is{0:.1f}%\".format(np.mean(original_scores) * 100))\n",
    "broken_scores = cross_val_score(estimator, x_broken, y,scoring='accuracy')\n",
    "print(\"The 'broken' average accuracy for is{0:.1f}%\".format(np.mean(broken_scores) * 100))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The average accuracy for is82.3%\n"
     ]
    }
   ],
   "source": [
    "# 预处理方式\n",
    "from sklearn.preprocessing import MinMaxScaler # MinMaxScaler类进行基于特征的规范化。\n",
    "x_transformed = MinMaxScaler().fit_transform(x_broken) #调用fit_transform()函数，即可完成训练和转换。\n",
    "estimator = KNeighborsClassifier()\n",
    "transformed_scores = cross_val_score(estimator,x_transformed,y,scoring=\"accuracy\")\n",
    "print(\"The average accuracy for is{0:.1f}%\".format(np.mean(transformed_scores) * 100))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "流水线的输入为一连串的数据挖掘步骤，其中最后一步必须是估计器，前几步是转换器。输\n",
    "入的数据集经过转换器的处理后，输出的结果作为下一步的输入。最后，用位于流水线最后一步\n",
    "的估计器对数据进行分类。我们流水线分为两大步。\n",
    "(1) 用MinMaxScaler将特征取值范围规范到0~1。\n",
    "(2) 指定KNeighborsClassifier分类器。\n",
    "每一步都用元组（‘名称’，步骤）来表示"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The pipeline scored an average accuracy for is 82.3%\n"
     ]
    }
   ],
   "source": [
    "# 流水线方法\n",
    "from sklearn.pipeline import Pipeline #创建流水线前，先导入Pipeline对象\n",
    "#流水线的核心是元素为元组的列表。第一个元组规范特征取值范围，第二个元组实现预测功能。\n",
    "#我们把第一步叫作规范特征取值（scale），第二步叫作预测（predict），也可以用其他名字。元组的第二部分是实际的转换器对象或估计器对象。\n",
    "scaling_pipeline = Pipeline([(\"scale\",MinMaxScaler()),('predict',KNeighborsClassifier())])\n",
    "\n",
    "scores = cross_val_score(scaling_pipeline,x_broken,y,scoring=\"accuracy\")\n",
    "print(\"The pipeline scored an average accuracy for is {0:.1f}%\".format(np.mean(transformed_scores) * 100))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
